package com.bw.baserecyclerview.quick;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.ListUpdateCallback;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

public abstract class BaseQuickMoreAdapter <T> extends RecyclerView.Adapter<BaseViewHolder>{

    private List<T> data = new ArrayList<>();
    private int p;
    private int c;
    private static final int HEADTYPE = -1;
    private static final int FOOTTYPE = -2;
    private int count = 0;
    //头布局viewholder
    private HeadViewHolder headViewHolder;
    //脚布局viewholder
    private FootViewHolder footViewHolder;
    //item点击监听器
    private BaseQuickAdapter.OnItemClickListener onItemClickListener;
    //子控件点击监听器
    private BaseQuickAdapter.OnItemChildClickListener onItemChildClickListener;
    //全部需要添加子控件监听的集合
    private List<Integer>ids = new ArrayList<>();
    protected Context context;

    //添加子控件监听方法
    protected void addItemChildClick(int ... id){
        for ( int i = 0;i < id.length;i ++){
            ids.add(id[i]);
        }
    }

    public void setOnItemChildClickListener(BaseQuickAdapter.OnItemChildClickListener onItemChildClickListener) {
        this.onItemChildClickListener = onItemChildClickListener;
    }

    public void setOnItemClickListener(BaseQuickAdapter.OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    private void bindListener(BaseViewHolder holder){
        //绑定item点击事件
        if (onItemClickListener!=null)
            holder.itemView.setOnClickListener(v->{
                onItemClickListener.onItemClick(this,holder.getAdapterPosition()-(headViewHolder==null?0:1));
            });
        if (onItemChildClickListener != null){
            for (Integer id : ids){
                holder.getView(id).setOnClickListener(v->{
                    onItemChildClickListener.onItemChildClick(this,id,holder.getAdapterPosition()-(headViewHolder==null?0:1));
                });
            }
        }
    }

    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        context = recyclerView.getContext();
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if (manager instanceof GridLayoutManager){
            //合并列->展示头布局实现1行一个头布局效果
            GridLayoutManager gridLayoutManager = (GridLayoutManager) manager;
            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    if (position == 0&&headViewHolder!=null)
                        return gridLayoutManager.getSpanCount();
                    if (position == getItemCount()-1&&footViewHolder!=null)
                        return gridLayoutManager.getSpanCount();
                    return 1;
                }
            });
        }
    }

    //设置头布局方法->存在多个头布局情况->多个头布局的view都添加到headviewholder的rootview下
    public void setHeaderView(View headerView){
        if (headViewHolder == null){
            LinearLayout linearLayout = new LinearLayout(headerView.getContext());
            linearLayout.setOrientation(LinearLayout.VERTICAL);
            ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            linearLayout.setLayoutParams(layoutParams);
            headViewHolder = new HeadViewHolder(linearLayout);
            count +=1;
        }
        headViewHolder.rootView.addView(headerView);
    }
    //设置脚布局方法
    public void setFootView(View footView){
        if (footViewHolder == null){
            LinearLayout linearLayout = new LinearLayout(footView.getContext());
            linearLayout.setOrientation(LinearLayout.VERTICAL);
            ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            linearLayout.setLayoutParams(layoutParams);
            footViewHolder = new FootViewHolder(linearLayout);
            count+=1;
        }
        footViewHolder.rootView.addView(footView);
    }

    //获取适配器关联数据源
    public List<T> getData() {
        return data;
    }

    //添加一条数据源
    public void add(T entity){
        data.add(entity);
        //局部刷新
        notifyItemInserted(data.size()-1);
    }
    //添加多条数据源
    public void adds(List<T>list){
        if (list == null)
            return;
        if (list.size() == 0)
            return;
        int position = data.size()-1;
        data.addAll(list);
        notifyItemRangeChanged(position,list.size());
    }
    //删除一条数据源
    public void remove(int position){
        if (position < 0)
            return;
        if (position>=data.size())
            return;
        data.remove(position);
        notifyItemRemoved(position);
    }

    //设置新数据源->由于当前方法涉及到适配下拉刷新逻辑->整体使用diffutil进行数据比对后在刷新
    public void setNewInstance(List<T>list){
        if (data.size() == 0){
            data.addAll(list);
            notifyDataSetChanged();
            return;
        }
        DiffUtil.DiffResult result = DiffUtil.calculateDiff(new BaseQuickDiff<T>(data,list));
        result.dispatchUpdatesTo(new ListUpdateCallback() {
            @Override
            public void onInserted(int position, int count) {
                List<T>datas = list.subList(position,count);
                data.addAll(position,datas);
                p=position;
                c = count;
            }

            @Override
            public void onRemoved(int position, int count) {
                int i = position+count-1;
                for (;i>=position;i--)
                    data.remove(i);
            }

            @Override
            public void onMoved(int fromPosition, int toPosition) {
            }

            @Override
            public void onChanged(int position, int count, @Nullable Object payload) {
                onRemoved(position,count);
                onInserted(position,count);
            }
        });
        notifyItemRangeChanged(p,c+(headViewHolder==null?0:1));
    }

    public abstract void convert(BaseViewHolder holder,T item);

    @NonNull
    @Override
    public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == HEADTYPE){
            return headViewHolder;
        }
        if (viewType == FOOTTYPE){
            return footViewHolder;
        }
        View itemView = createItemView(viewType);
        BaseViewHolder baseViewHolder = new BaseViewHolder(itemView);
        //创建viewholder对象时绑定对应监听
        bindListener(baseViewHolder);
        return baseViewHolder;
    }

    protected abstract View createItemView(int viewType);

    //区分列表的头布局以及脚布局
    @Override
    public int getItemViewType(int position) {
        if (position==0 && headViewHolder != null)
            return HEADTYPE;
        else if (position == (getItemCount()-1)&&footViewHolder!=null)
            return FOOTTYPE;
        return getItemType(position);
    }

    public abstract int getItemType(int position);

    @Override
    public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
        if (holder instanceof  HeadViewHolder || holder instanceof  FootViewHolder)
            return;
        T item = data.get(position-(headViewHolder == null?0:1));
        convert(holder,item);
    }

    @Override
    public int getItemCount() {
        return data.size()+count;//由于添加头布局以及脚布局问题->需要在原有数据源的长度的基础上添加出头布局以及脚布局数量
    }

    //item点击监听回调
    public interface OnItemClickListener{
        void onItemClick(BaseQuickAdapter adapter,int possition);
    }
    //itemchild点击监听回调
    public interface OnItemChildClickListener{
        void onItemChildClick(BaseQuickAdapter adapter,int id,int possition);
    }
}
